package files

import (
	"net/http"
	"strconv"

	"gitee.com/xuender/reader/pb"
	"github.com/gin-gonic/gin"
)

// Ctrl 文件控制.
type Ctrl struct {
	config *pb.Config
	s      *Service
	as     *ArchiveService
}

// NewCtrl 新建文件控制.
func NewCtrl(
	config *pb.Config,
	s *Service,
	as *ArchiveService,
) *Ctrl {
	return &Ctrl{
		config: config,
		s:      s,
		as:     as,
	}
}

// Router 路由.
func (p *Ctrl) Router(group *gin.RouterGroup) {
	p.s.Root(p.config.Paths...)
	group.GET("/folder/:id", p.folder)
	group.GET("/info/:id", p.info)
	group.GET("/original/:id", p.original)
	group.GET("/text/:id", p.text)
}

func (p *Ctrl) text(ctx *gin.Context) {
	var offset int64
	if i, err := strconv.ParseInt(ctx.Query("offset"), 10, 64); err == nil {
		offset = i
	}

	if ctx.DefaultQuery("next", "_") != "_" {
		offset += p.config.MaxTextLine
	}

	if ctx.DefaultQuery("prev", "_") != "_" {
		offset -= p.config.MaxTextLine
	}

	if offset < 0 {
		offset = 0
	}

	ctx.ProtoBuf(http.StatusOK, p.s.GetText(ctx.Param("id"), offset))
}

func (p *Ctrl) original(ctx *gin.Context) {
	id := ctx.Param("id")

	fi, has := p.s.File(id)
	if !has {
		ctx.String(http.StatusNotFound, "未找到:"+id)

		return
	}

	if fi.Archive == "" {
		ctx.File(fi.Path)

		return
	}

	p.as.Write(fi, ctx.Writer)
}

func (p *Ctrl) folder(ctx *gin.Context) {
	var o int64

	if i, err := strconv.ParseInt(ctx.Query("offset"), 10, 64); err == nil {
		o = i
	}

	ctx.ProtoBuf(http.StatusOK, p.s.GetFolder(ctx.Param("id"), o))
}

func (p *Ctrl) info(ctx *gin.Context) {
	id := ctx.Param("id")

	if fi, has := p.s.File(id); has {
		ctx.ProtoBuf(http.StatusOK, fi)

		return
	}

	ctx.ProtoBuf(http.StatusNotFound, &pb.FileInfo{
		Id:   id,
		Name: "未知的文件",
	})
}
